package convert

import (
	"errors"
	"fmt"
	"reflect"
)

// AnyToInt 任意基础类型转为int类型.
// 注意：浮点数到int的转换会丢失小数部分。
func AnyToInt(value any) (int, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return value.(int), nil
	case reflect.Int8:
		return Int8ToInt(value.(int8))
	case reflect.Int16:
		return Int16ToInt(value.(int16))
	case reflect.Int32:
		return Int32ToInt(value.(int32))
	case reflect.Int64:
		return Int64ToInt(value.(int64))
	case reflect.Uint:
		return UintToInt(value.(uint))
	case reflect.Uint8:
		return Uint8ToInt(value.(uint8))
	case reflect.Uint16:
		return Uint16ToInt(value.(uint16))
	case reflect.Uint32:
		return Uint32ToInt(value.(uint32))
	case reflect.Uint64:
		return Uint64ToInt(value.(uint64))
	case reflect.Float32:
		return Float32ToInt(value.(float32))
	case reflect.Float64:
		return Float64ToInt(value.(float64))
	case reflect.String:
		return StringToInt(value.(string))
	case reflect.Bool:
		return BoolToInt(value.(bool)), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToInt8 任意基础类型转为int8类型.
// 注意：浮点数到int8的转换会丢失小数部分。
func AnyToInt8(value any) (int8, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToInt8(value.(int))
	case reflect.Int8:
		return value.(int8), nil
	case reflect.Int16:
		return Int16ToInt8(value.(int16))
	case reflect.Int32:
		return Int32ToInt8(value.(int32))
	case reflect.Int64:
		return Int64ToInt8(value.(int64))
	case reflect.Uint:
		return UintToInt8(value.(uint))
	case reflect.Uint8:
		return Uint8ToInt8(value.(uint8))
	case reflect.Uint16:
		return Uint16ToInt8(value.(uint16))
	case reflect.Uint32:
		return Uint32ToInt8(value.(uint32))
	case reflect.Uint64:
		return Uint64ToInt8(value.(uint64))
	case reflect.Float32:
		return Float32ToInt8(value.(float32))
	case reflect.Float64:
		return Float64ToInt8(value.(float64))
	case reflect.String:
		return StringToInt8(value.(string))
	case reflect.Bool:
		return int8(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToInt16 任意基础类型转为int16类型.
// 注意：浮点数到int16的转换会丢失小数部分。
func AnyToInt16(value any) (int16, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToInt16(value.(int))
	case reflect.Int8:
		return Int8ToInt16(value.(int8))
	case reflect.Int16:
		return value.(int16), nil
	case reflect.Int32:
		return Int32ToInt16(value.(int32))
	case reflect.Int64:
		return Int64ToInt16(value.(int64))
	case reflect.Uint:
		return UintToInt16(value.(uint))
	case reflect.Uint8:
		return Uint8ToInt16(value.(uint8))
	case reflect.Uint16:
		return Uint16ToInt16(value.(uint16))
	case reflect.Uint32:
		return Uint32ToInt16(value.(uint32))
	case reflect.Uint64:
		return Uint64ToInt16(value.(uint64))
	case reflect.Float32:
		return Float32ToInt16(value.(float32))
	case reflect.Float64:
		return Float64ToInt16(value.(float64))
	case reflect.String:
		return StringToInt16(value.(string))
	case reflect.Bool:
		return int16(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToInt32 任意基础类型转为int32类型.
// 注意：浮点数到int32的转换会丢失小数部分。
func AnyToInt32(value any) (int32, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToInt32(value.(int))
	case reflect.Int8:
		return Int8ToInt32(value.(int8))
	case reflect.Int16:
		return Int16ToInt32(value.(int16))
	case reflect.Int32:
		return value.(int32), nil
	case reflect.Int64:
		return Int64ToInt32(value.(int64))
	case reflect.Uint:
		return UintToInt32(value.(uint))
	case reflect.Uint8:
		return Uint8ToInt32(value.(uint8))
	case reflect.Uint16:
		return Uint16ToInt32(value.(uint16))
	case reflect.Uint32:
		return Uint32ToInt32(value.(uint32))
	case reflect.Uint64:
		return Uint64ToInt32(value.(uint64))
	case reflect.Float32:
		return Float32ToInt32(value.(float32))
	case reflect.Float64:
		return Float64ToInt32(value.(float64))
	case reflect.String:
		return StringToInt32(value.(string))
	case reflect.Bool:
		return int32(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToInt64 任意基础类型转为int64类型.
// 注意：浮点数到int64的转换会丢失小数部分。
func AnyToInt64(value any) (int64, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToInt64(value.(int))
	case reflect.Int8:
		return Int8ToInt64(value.(int8))
	case reflect.Int16:
		return Int16ToInt64(value.(int16))
	case reflect.Int32:
		return Int32ToInt64(value.(int32))
	case reflect.Int64:
		return value.(int64), nil
	case reflect.Uint:
		return UintToInt64(value.(uint))
	case reflect.Uint8:
		return Uint8ToInt64(value.(uint8))
	case reflect.Uint16:
		return Uint16ToInt64(value.(uint16))
	case reflect.Uint32:
		return Uint32ToInt64(value.(uint32))
	case reflect.Uint64:
		return Uint64ToInt64(value.(uint64))
	case reflect.Float32:
		return Float32ToInt64(value.(float32))
	case reflect.Float64:
		return Float64ToInt64(value.(float64))
	case reflect.String:
		return StringToInt64(value.(string))
	case reflect.Bool:
		return int64(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToUint 任意基础类型转为uint类型.
// 注意：浮点数到int的转换会丢失小数部分。
func AnyToUint(value any) (uint, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToUint(value.(int))
	case reflect.Int8:
		return Int8ToUint(value.(int8))
	case reflect.Int16:
		return Int16ToUint(value.(int16))
	case reflect.Int32:
		return Int32ToUint(value.(int32))
	case reflect.Int64:
		return Int64ToUint(value.(int64))
	case reflect.Uint:
		return value.(uint), nil
	case reflect.Uint8:
		return Uint8ToUint(value.(uint8))
	case reflect.Uint16:
		return Uint16ToUint(value.(uint16))
	case reflect.Uint32:
		return Uint32ToUint(value.(uint32))
	case reflect.Uint64:
		return Uint64ToUint(value.(uint64))
	case reflect.Float32:
		return Float32ToUint(value.(float32))
	case reflect.Float64:
		return Float64ToUint(value.(float64))
	case reflect.String:
		return StringToUint(value.(string))
	case reflect.Bool:
		return uint(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToUint8 任意基础类型转为uint8类型.
// 注意：浮点数到int8的转换会丢失小数部分。
func AnyToUint8(value any) (uint8, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToUint8(value.(int))
	case reflect.Int8:
		return Int8ToUint8(value.(int8))
	case reflect.Int16:
		return Int16ToUint8(value.(int16))
	case reflect.Int32:
		return Int32ToUint8(value.(int32))
	case reflect.Int64:
		return Int64ToUint8(value.(int64))
	case reflect.Uint:
		return UintToUint8(value.(uint))
	case reflect.Uint8:
		return value.(uint8), nil
	case reflect.Uint16:
		return Uint16ToUint8(value.(uint16))
	case reflect.Uint32:
		return Uint32ToUint8(value.(uint32))
	case reflect.Uint64:
		return Uint64ToUint8(value.(uint64))
	case reflect.Float32:
		return Float32ToUint8(value.(float32))
	case reflect.Float64:
		return Float64ToUint8(value.(float64))
	case reflect.String:
		return StringToUint8(value.(string))
	case reflect.Bool:
		return uint8(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToUint16 任意基础类型转为uint16类型.
// 注意：浮点数到int16的转换会丢失小数部分。
func AnyToUint16(value any) (uint16, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToUint16(value.(int))
	case reflect.Int8:
		return Int8ToUint16(value.(int8))
	case reflect.Int16:
		return Int16ToUint16(value.(int16))
	case reflect.Int32:
		return Int32ToUint16(value.(int32))
	case reflect.Int64:
		return Int64ToUint16(value.(int64))
	case reflect.Uint:
		return UintToUint16(value.(uint))
	case reflect.Uint8:
		return Uint8ToUint16(value.(uint8))
	case reflect.Uint16:
		return value.(uint16), nil
	case reflect.Uint32:
		return Uint32ToUint16(value.(uint32))
	case reflect.Uint64:
		return Uint64ToUint16(value.(uint64))
	case reflect.Float32:
		return Float32ToUint16(value.(float32))
	case reflect.Float64:
		return Float64ToUint16(value.(float64))
	case reflect.String:
		return StringToUint16(value.(string))
	case reflect.Bool:
		return uint16(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToUint32 任意基础类型转为uint32类型.
// 注意：浮点数到int32的转换会丢失小数部分。
func AnyToUint32(value any) (uint32, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToUint32(value.(int))
	case reflect.Int8:
		return Int8ToUint32(value.(int8))
	case reflect.Int16:
		return Int16ToUint32(value.(int16))
	case reflect.Int32:
		return Int32ToUint32(value.(int32))
	case reflect.Int64:
		return Int64ToUint32(value.(int64))
	case reflect.Uint:
		return UintToUint32(value.(uint))
	case reflect.Uint8:
		return Uint8ToUint32(value.(uint8))
	case reflect.Uint16:
		return Uint16ToUint32(value.(uint16))
	case reflect.Uint32:
		return value.(uint32), nil
	case reflect.Uint64:
		return Uint64ToUint32(value.(uint64))
	case reflect.Float32:
		return Float32ToUint32(value.(float32))
	case reflect.Float64:
		return Float64ToUint32(value.(float64))
	case reflect.String:
		return StringToUint32(value.(string))
	case reflect.Bool:
		return uint32(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToUint64 任意基础类型转为uint64类型.
// 注意：浮点数到int64的转换会丢失小数部分。
func AnyToUint64(value any) (uint64, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToUint64(value.(int))
	case reflect.Int8:
		return Int8ToUint64(value.(int8))
	case reflect.Int16:
		return Int16ToUint64(value.(int16))
	case reflect.Int32:
		return Int32ToUint64(value.(int32))
	case reflect.Int64:
		return Int64ToUint64(value.(int64))
	case reflect.Uint:
		return UintToUint64(value.(uint))
	case reflect.Uint8:
		return Uint8ToUint64(value.(uint8))
	case reflect.Uint16:
		return Uint16ToUint64(value.(uint16))
	case reflect.Uint32:
		return Uint32ToUint64(value.(uint32))
	case reflect.Uint64:
		return value.(uint64), nil
	case reflect.Float32:
		return Float32ToUint64(value.(float32))
	case reflect.Float64:
		return Float64ToUint64(value.(float64))
	case reflect.String:
		return StringToUint64(value.(string))
	case reflect.Bool:
		return uint64(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToFloat32 任意基础类型转为float32类型.
func AnyToFloat32(value any) (float32, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToFloat32(value.(int))
	case reflect.Int8:
		return Int8ToFloat32(value.(int8))
	case reflect.Int16:
		return Int16ToFloat32(value.(int16))
	case reflect.Int32:
		return Int32ToFloat32(value.(int32))
	case reflect.Int64:
		return Int64ToFloat32(value.(int64))
	case reflect.Uint:
		return UintToFloat32(value.(uint))
	case reflect.Uint8:
		return Uint8ToFloat32(value.(uint8))
	case reflect.Uint16:
		return Uint16ToFloat32(value.(uint16))
	case reflect.Uint32:
		return Uint32ToFloat32(value.(uint32))
	case reflect.Uint64:
		return Uint64ToFloat32(value.(uint64))
	case reflect.Float32:
		return value.(float32), nil
	case reflect.Float64:
		return Float64ToFloat32(value.(float64))
	case reflect.String:
		return StringToFloat32(value.(string))
	case reflect.Bool:
		return float32(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToFloat64 任意基础类型转为float64类型.
func AnyToFloat64(value any) (float64, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToFloat64(value.(int))
	case reflect.Int8:
		return Int8ToFloat64(value.(int8))
	case reflect.Int16:
		return Int16ToFloat64(value.(int16))
	case reflect.Int32:
		return Int32ToFloat64(value.(int32))
	case reflect.Int64:
		return Int64ToFloat64(value.(int64))
	case reflect.Uint:
		return UintToFloat64(value.(uint))
	case reflect.Uint8:
		return Uint8ToFloat64(value.(uint8))
	case reflect.Uint16:
		return Uint16ToFloat64(value.(uint16))
	case reflect.Uint32:
		return Uint32ToFloat64(value.(uint32))
	case reflect.Uint64:
		return Uint64ToFloat64(value.(uint64))
	case reflect.Float32:
		return Float32ToFloat64(value.(float32))
	case reflect.Float64:
		return value.(float64), nil
	case reflect.String:
		return StringToFloat64(value.(string))
	case reflect.Bool:
		return float64(BoolToInt(value.(bool))), nil
	default:
		return 0, errors.New("unsupported type")
	}
}

// AnyToString 任意基础类型转为string类型.
func AnyToString(value any) (string, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToString(value.(int)), nil
	case reflect.Int8:
		return Int8ToString(value.(int8)), nil
	case reflect.Int16:
		return Int16ToString(value.(int16)), nil
	case reflect.Int32:
		return Int32ToString(value.(int32)), nil
	case reflect.Int64:
		return Int64ToString(value.(int64)), nil
	case reflect.Uint:
		return UintToString(value.(uint)), nil
	case reflect.Uint8:
		return Uint8ToString(value.(uint8)), nil
	case reflect.Uint16:
		return Uint16ToString(value.(uint16)), nil
	case reflect.Uint32:
		return Uint32ToString(value.(uint32)), nil
	case reflect.Uint64:
		return Uint64ToString(value.(uint64)), nil
	case reflect.Float32:
		return Float32ToString(value.(float32)), nil
	case reflect.Float64:
		return Float64ToString(value.(float64)), nil
	case reflect.String:
		return value.(string), nil
	case reflect.Bool:
		return BoolToString(value.(bool)), nil
	default:
		return "", errors.New("unsupported type")
	}
}

// AnyToBool 任意基础类型转为bool类型.
func AnyToBool(value any) (bool, error) {
	val := reflect.TypeOf(value)
	switch val.Kind() {
	case reflect.Int:
		return IntToBool(value.(int)), nil
	case reflect.Int8:
		return Int8ToBool(value.(int8)), nil
	case reflect.Int16:
		return Int16ToBool(value.(int16)), nil
	case reflect.Int32:
		return Int32ToBool(value.(int32)), nil
	case reflect.Int64:
		return Int64ToBool(value.(int64)), nil
	case reflect.Uint:
		return UintToBool(value.(uint)), nil
	case reflect.Uint8:
		return Uint8ToBool(value.(uint8)), nil
	case reflect.Uint16:
		return Uint16ToBool(value.(uint16)), nil
	case reflect.Uint32:
		return Uint32ToBool(value.(uint32)), nil
	case reflect.Uint64:
		return Uint64ToBool(value.(uint64)), nil
	case reflect.Float32:
		return Float32ToBool(value.(float32)), nil
	case reflect.Float64:
		return Float64ToBool(value.(float64)), nil
	case reflect.String:
		return StringToBool(value.(string))
	case reflect.Bool:
		return value.(bool), nil
	default:
		return false, errors.New("unsupported type")
	}
}

// AnyToAny 任意基础类型转为任意基础类型
// dstPtr为目标变量的指针
func AnyToAny(src any, dstPtr any) error {
	srcVal := reflect.ValueOf(src)
	dstVal := reflect.ValueOf(dstPtr)

	// 验证dst是否为指针类型
	if dstVal.Kind() != reflect.Ptr {
		return fmt.Errorf("dst needs to be a pointer")
	}

	// 获取指针指向的值
	dstElem := dstVal.Elem()

	// 如果类型一致，则直接赋值返回
	if srcVal.Type() == dstElem.Type() {
		dstElem.Set(srcVal)
		return nil
	}

	// 根据dst的类型，调用相应的转换函数
	switch dstElem.Kind() {
	case reflect.Int:
		if val, err := AnyToInt(src); err == nil {
			dstElem.SetInt(int64(val))
		} else {
			return err
		}
	case reflect.Int8:
		if val, err := AnyToInt8(src); err == nil {
			dstElem.SetInt(int64(val))
		} else {
			return err
		}
	case reflect.Int16:
		if val, err := AnyToInt16(src); err == nil {
			dstElem.SetInt(int64(val))
		} else {
			return err
		}
	case reflect.Int32:
		if val, err := AnyToInt32(src); err == nil {
			dstElem.SetInt(int64(val))
		} else {
			return err
		}
	case reflect.Int64:
		if val, err := AnyToInt64(src); err == nil {
			dstElem.SetInt(val)
		} else {
			return err
		}
	case reflect.Uint:
		if val, err := AnyToUint(src); err == nil {
			dstElem.SetUint(uint64(val))
		} else {
			return err
		}
	case reflect.Uint8:
		if val, err := AnyToUint8(src); err == nil {
			dstElem.SetUint(uint64(val))
		} else {
			return err
		}
	case reflect.Uint16:
		if val, err := AnyToUint16(src); err == nil {
			dstElem.SetUint(uint64(val))
		} else {
			return err
		}
	case reflect.Uint32:
		if val, err := AnyToUint32(src); err == nil {
			dstElem.SetUint(uint64(val))
		} else {
			return err
		}
	case reflect.Uint64:
		if val, err := AnyToUint64(src); err == nil {
			dstElem.SetUint(val)
		} else {
			return err
		}
	case reflect.Float32:
		if val, err := AnyToFloat32(src); err == nil {
			dstElem.SetFloat(float64(val))
		} else {
			return err
		}
	case reflect.Float64:
		if val, err := AnyToFloat64(src); err == nil {
			dstElem.SetFloat(val)
		} else {
			return err
		}
	case reflect.String:
		if val, err := AnyToString(src); err == nil {
			dstElem.SetString(val)
		} else {
			return err
		}
	case reflect.Bool:
		if val, err := AnyToBool(src); err == nil {
			dstElem.SetBool(val)
		} else {
			return err
		}
	default:
		return fmt.Errorf("unsupported type: %v", dstElem.Type())
	}
	return nil
}
